package com.ibeeking.found.cop.b.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.cop.b.rest.service.IDataTalkGroupService;
import com.ibeeking.found.cop.b.rest.service.IWxOpenService;
import com.ibeeking.found.cop.service.common.dos.*;
import com.ibeeking.found.cop.service.common.param.DataTalkGroupParam;
import com.ibeeking.found.cop.service.common.query.DataTalkGroupQuery;
import com.ibeeking.found.cop.service.common.vo.DataTalkGroupVO;
import com.ibeeking.found.cop.service.mapper.DataTalkGroupFriendsMapper;
import com.ibeeking.found.cop.service.mapper.DataTalkGroupMapper;
import com.ibeeking.found.cop.service.mapper.GroupFriendsMapper;
import com.ibeeking.found.cop.service.mapper.GroupMapper;
import com.ibeeking.found.id.GenerateId;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.date.DateUtil;
import com.ibeeking.nematos.utils.id.IdGenerator;
import com.ibeeking.nematos.utils.json.JsonUtils;
import me.chanjar.weixin.cp.api.WxCpMsgAuditService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.msgaudit.WxCpGroupChat;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName DataTalkGroupServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-27 18:50
 **/
@Service
public class DataTalkGroupServiceImpl extends ServiceImpl<DataTalkGroupMapper, DataTalkGroupDO> implements IDataTalkGroupService {

    @Resource
    private DataTalkGroupMapper dataTalkGroupMapper;

    @Resource
    private DataTalkGroupFriendsMapper dataTalkGroupFriendsMapper;

    @Resource
    private GroupMapper groupMapper;

    @Resource
    private GroupFriendsMapper groupFriendsMapper;

    @Resource
    private IWxOpenService wxOpenServiceImpl;

    @Override
    public List<DataTalkGroupVO> list(DataTalkGroupQuery query) {
        List<DataTalkGroupDO> entityDOS = dataTalkGroupMapper.selectList(new LambdaQueryWrapper<DataTalkGroupDO>()
                .eq(query.getId() != null, DataTalkGroupDO::getId, query.getId())
                .eq(query.getGroupId() != null, DataTalkGroupDO::getGroupId, query.getGroupId())
                .eq(StringUtils.isNotBlank(query.getChatId()), DataTalkGroupDO::getChatId, query.getChatId())
                .like(StringUtils.isNotBlank(query.getGroupName()), DataTalkGroupDO::getGroupName, query.getGroupName())
                .orderByDesc(DataTalkGroupDO::getCreateTime)
        );
        List<DataTalkGroupVO> entityVOS = JsonUtils.jsonToList(entityDOS, DataTalkGroupVO.class);
        return entityVOS;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(DataTalkGroupParam param) {
        DataTalkGroupDO entityDO = BeanUtil.convertBean(param, DataTalkGroupDO.class);
        entityDO.setId(GenerateId.generateId());
        entityDO.setCreateTime(LocalDateTime.now());
        return dataTalkGroupMapper.insert(entityDO) > 0;
    }

    @Override
    public DataTalkGroupVO view(Long id) {
        DataTalkGroupDO entityDO = dataTalkGroupMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        DataTalkGroupVO entityVO = BeanUtil.convertBean(entityDO, DataTalkGroupVO.class);
        return entityVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean syncBatchDataTalkGroupFromWxCp(Long tenantId){
        try {
            WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId);
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }
            WxCpMsgAuditService wxCpMsgAuditService = wxCpService.getMsgAuditService();
            if(wxCpMsgAuditService == null)  throw new BusinessException("获取企微会话存档服务异常!");

            List<GroupDO> groupDOList = groupMapper.selectList(new LambdaQueryWrapper<GroupDO>());
            Map<String, Long> validChatIdMap = Collections3.isNotEmpty(groupDOList)?groupDOList.stream().filter(d-> StringUtils.isNotEmpty(d.getChatId())).collect(Collectors.toMap(GroupDO::getChatId, GroupDO::getId, (o, n) -> n)):null;
            LogUtils.info(">>>>>>>validChatIdMap:{}",JsonUtils.toJsonStr(validChatIdMap));
            List<DataTalkGroupDO> dataTalkGroupDOList = new ArrayList<>();
            List<DataTalkGroupFriendsDO> dataTalkGroupFriendsDOList = new ArrayList<>();
            if(validChatIdMap!=null && validChatIdMap.size()>0) {
                for (String chatId : validChatIdMap.keySet()) {
                    WxCpGroupChat wxCpGroupChat = wxCpMsgAuditService.getGroupChat(chatId);
                    LogUtils.info(">>>>>>>WxCpGroupChat:{}",JsonUtils.toJsonStr(wxCpGroupChat));
                    if (wxCpGroupChat != null) {
                        DataTalkGroupDO groupDO = new DataTalkGroupDO();
                        Long talkGroupid = IdGenerator.getId();
                        groupDO.setId(talkGroupid);
                        groupDO.setCreateTime(LocalDateTime.now());
                        groupDO.setGroupId(validChatIdMap.get(chatId));
                        groupDO.setChatId(chatId);
                        groupDO.setGroupName(wxCpGroupChat.getRoomName());
                        groupDO.setNotice(wxCpGroupChat.getNotice());
                        Long roomCreateTime = wxCpGroupChat.getRoomCreateTime();
                        if (roomCreateTime != null) {
                            LocalDateTime buildTime = DateUtil.longToLocalDateTime(roomCreateTime);
                            groupDO.setBuildTime(buildTime);
                        }
                        groupDO.setBuilder(wxCpGroupChat.getCreator());
                        dataTalkGroupDOList.add(groupDO);
                        List<GroupFriendsDO> groupFriendsDOList = groupFriendsMapper.selectList(new LambdaQueryWrapper<GroupFriendsDO>().eq(GroupFriendsDO::getChatId,chatId));
                        Map<String,Long> groupFriendsIdMap = Collections3.isNotEmpty(groupFriendsDOList)?groupFriendsDOList.stream().collect(Collectors.toMap(GroupFriendsDO::getFriendsCode, GroupFriendsDO::getFriendsId, (o, n) -> n)):null;
                        List<WxCpGroupChat.Member> groupChatMemberList = wxCpGroupChat.getMembers();
                        if (Collections3.isNotEmpty(groupChatMemberList)) {
                            for (WxCpGroupChat.Member member : groupChatMemberList) {
                                DataTalkGroupFriendsDO groupFriendsDO = new DataTalkGroupFriendsDO();
                                groupFriendsDO.setId(IdGenerator.getId());
                                groupFriendsDO.setCreateTime(LocalDateTime.now());
                                groupFriendsDO.setTalkGroupId(talkGroupid);
                                groupFriendsDO.setChatId(chatId);
                                groupFriendsDO.setGroupId(validChatIdMap.get(chatId));
                                groupFriendsDO.setFriendsCode(member.getMemberId());
                                groupFriendsDO.setFriendsId(groupFriendsIdMap!=null?groupFriendsIdMap.get(member.getMemberId()):null);
                                Long memberJoinTime = member.getJoinTime();
                                if (memberJoinTime != null) {
                                    LocalDateTime joinTime = DateUtil.longToLocalDateTime(memberJoinTime);
                                    groupFriendsDO.setJoinTime(joinTime);
                                }
                                dataTalkGroupFriendsDOList.add(groupFriendsDO);
                            }
                        }
                    }
                }
            }
            if(Collections3.isNotEmpty(dataTalkGroupDOList)){
                dataTalkGroupMapper.insertBatchSomeColumn(dataTalkGroupDOList);
            }
            if(Collections3.isNotEmpty(dataTalkGroupFriendsDOList)){
                dataTalkGroupFriendsMapper.insertBatchSomeColumn(dataTalkGroupFriendsDOList);
            }
            return true;
        } catch (Exception e) {
            LogUtils.error("同步群聊及成员处理异常:{}", e);
            return false;
        }
    }
}

